#!/usr/bin/env python
# yongming.li 

import sys
import os
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from ParseNative import *
from MyHighlighter import *


class FindbugForm(QDialog):

    def setOpenFileName(self,mylabel):    
        options = QtGui.QFileDialog.Options()

        fileName = QtGui.QFileDialog.getOpenFileName(self,
                "QFileDialog.getOpenFileName()",
                mylabel.text(),
                "All Files (*);;Text Files (*.txt)",'', options)
        if fileName:
            mylabel.setText(fileName)

    def  getobjFile(self):
         self.setOpenFileName(self.objFileNameLabel)
         name = self.objFileNameLabel.text()
         print 'name is ' + name
         cmd = self.myPath+'/objdump -S %s '%(name)
         print 'cmd is ' + cmd 
         lines = os.popen(cmd).readlines()
         
         cmd = cmd + ' > ./code.asm'
         os.popen(cmd)
         for  line  in lines: 
             s=line.strip()
             self.codeedit.append(s)
         results=parsesnative_get_code_from_pc(lines,self.my_pc)

         for line in results:
             line = line.strip()
             self.resultsedit.append(line)
         
    def  getlogFile(self):
         self.setOpenFileName(self.logFileNameLabel)
         name = self.logFileNameLabel.text()
         cmd = 'cat  %s '%(name)
         print 'cmd is ' + cmd 
         lines = os.popen(cmd).readlines()
         ret = parsesnative_crash_pc(lines)
         for line in ret:
             print line
             line = line.strip()
             items = line.split()
             self.usefullogedit.append(line)
             if items[0] == '#00':
                 print items[0]
                 self.my_pc = items[2]
                 self.my_filename = items[3]
                 self.my_pc=getshortPC(self.my_pc)
                 break

         print self.my_pc
         
 
    def  showselectpathorfile(self):
        self.fileorpathbox = QtGui.QGroupBox("select file or path:")
        layout = QtGui.QVBoxLayout()
    
        self.logFileNameLabel = QtGui.QLabel()
        self.logFileNameLabel.setFrameStyle(self.frameStyle)
        self.logFileNameLabel.setMaximumHeight(50)
        self.logFileNameLabel.setMinimumWidth (600)
        self.logFileNameLabel.setAcceptDrops(True)
        

        self.objFileNameLabel = QtGui.QLabel()
        self.objFileNameLabel.setFrameStyle(self.frameStyle)
        self.objFileNameLabel.setMaximumHeight(50)

        self.logFileNameButton = QtGui.QPushButton("select the log")
        self.objFileNameButton = QtGui.QPushButton("select obj file ")
        self.logFileNameButton.setMaximumWidth(200)
        self.objFileNameButton.setMaximumWidth(200)
        self.logFileNameButton.clicked.connect(self.getlogFile)
        self.objFileNameButton.clicked.connect(self.getobjFile)
        
        layout.addWidget(self.logFileNameButton)
        layout.addWidget(self.logFileNameLabel)
        layout.addWidget(self.objFileNameButton)
        layout.addWidget(self.objFileNameLabel)
        self.fileorpathbox.show()
        self.fileorpathbox.setLayout(layout)


    def  showfindbugresult(self):
        self.resultbox = QtGui.QGroupBox("show analyze result :")
        layout = QtGui.QVBoxLayout()
        self.resultsedit = QtGui.QTextEdit('')
        
        self.resultsedit.setTextColor(QColor(255, 0, 0, 255))

        self.resultsedit.setMinimumSize(300,350)
        layout.addWidget(self.resultsedit)

        self.resultbox.show()
        self.resultbox.setLayout(layout)

    def showcode(self):

        self.showcodebox = QtGui.QGroupBox("show code:")
        layout = QtGui.QHBoxLayout()
        self.mycodes = """
        """
        self.codeedit = QtGui.QTextEdit('')
        self.codeedit.append(self.mycodes)
        self.codeedit.setMinimumSize(400,400)
        layout.addWidget(self.codeedit)
        self.showcodebox.show()
        self.showcodebox.setLayout(layout)

    def showusefullog(self):
        self.showfindbugresult()
        self.showusefullogbox = QtGui.QGroupBox("show useful log:")
        layout = QtGui.QVBoxLayout()
 
        self.usefullogedit = QtGui.QTextEdit('')
        self.highlighter = MyHighlighter(self.usefullogedit.document())
        
        self.usefullogedit.setTextColor(QColor(0, 255, 0, 255))
        layout.addWidget(self.usefullogedit)
        layout.addWidget(self.resultbox)
        self.showusefullogbox.show()
        self.showusefullogbox.setLayout(layout)


    def  showfindbugsteps(self):
        self.showselectpathorfile()
        self.showcode()
        self.showstepsbox = QtGui.QGroupBox("find native crush steps :")
        #self.showstepsbox.setStyleSheet('border:1px')
        vlayout = QtGui.QVBoxLayout()
        hlayout = QtGui.QHBoxLayout()
        steps = """
=======================================================
0  get the log via adb logcat
1  find string like :
  '.+pc.([0-9a-f]{8}).+%s'
2 select the right obj file
3 auto : objdump -S
  when you select obj file
  (-S,source code with disassembly)
  and make sure use the same 
  version (gcc/g++ vs objdump)
or you will see error:
BFD: Dwarf Error: mangled line number section
4 show the source code
5 show analyze resules
6  more tools you can use :
    0   readelf
    1  addr2line
    2  gdb  (use core dump)
    3  ulimit ???
========================================================
""" 
        self.stepsLabel = QtGui.QLabel(steps)
        #self.editor.setMinimumSize(300,400)
        hlayout.addWidget(self.stepsLabel)
        hlayout.addWidget(self.showcodebox)
        vlayout.addLayout(hlayout)
        vlayout.addWidget(self.fileorpathbox)
        
        self.showstepsbox.show()
        self.showstepsbox.setLayout(vlayout)

    def __init__(self, parent=None):
        print 'init findbug'

        self.myPath = os.path.dirname(__file__)
        print self.myPath

        super(FindbugForm, self).__init__(parent)
        self.frameStyle = QtGui.QFrame.Sunken | QtGui.QFrame.Panel
        self.showfindbugsteps()
        self.showusefullog()
        

        mainLayout = QGridLayout()
        
        self.setWindowTitle("find bug")

        mainLayout.addWidget(self.showstepsbox,0,0)
        mainLayout.addWidget(self.showusefullogbox,0,1)

        self.setLayout(mainLayout)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = None
    form = FindbugForm()
    sys.exit(app.exec_())




